#python manage.py makemigrations
#python manage.py migrate
import uuid
from django.db import models
from django.contrib.auth.models import User
from django.core.files.storage import default_storage
import os
import logging
import requests
from django.utils import timezone
from datetime import datetime

logger = logging.getLogger(__name__)

def user_video_upload_path(instance, filename):
    """生成视频文件的上传路径"""
    ext = filename.split('.')[-1]
    filename = f"{uuid.uuid4().hex}.{ext}"
    return f"videos/{filename}"

class Video(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    video = models.FileField(upload_to=user_video_upload_path)
    detected_video = models.FileField(
        upload_to=user_video_upload_path, 
        null=True, 
        blank=True
    )
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.user.username}'s video - {self.uploaded_at}"

    def save(self, *args, **kwargs):
        try:
            super().save(*args, **kwargs)
            if self.video:
                logger.info(f"本地保存视频成功，文件名: {self.video.name}")
                self.video.close()
                if not os.path.exists(self.video.path):
                    logger.error(f"本地文件保存失败，路径: {self.video.path}")
                    self.delete()
                    raise RuntimeError("本地文件保存失败")
                file_size = os.path.getsize(self.video.path)
                if file_size <= 0:
                    self.delete()
                    raise RuntimeError("上传的文件大小为0")
            else:
                logger.error("视频文件为空")
        except Exception as e:
            if self.video and os.path.exists(self.video.path):
                try:
                    os.remove(self.video.path)
                except Exception as remove_error:
                    logger.error(f"删除本地文件失败: {str(remove_error)}")
            raise

class Image(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='images/')
    detected_image = models.ImageField(upload_to='detected_images/', null=True, blank=True)
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.user.username


class DetectionResult(models.Model):
    video = models.ForeignKey('Video', on_delete=models.CASCADE, related_name='detections')
    class_id = models.IntegerField()
    class_name = models.CharField(max_length=100)
    start_time = models.FloatField()
    end_time = models.FloatField()
    confidence = models.FloatField()
    count = models.IntegerField(default=1)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['video', 'start_time']


class RealtimeMonitoring(models.Model):
    """检测会话模型，表示一次完整的检测过程"""
    id = models.AutoField(primary_key=True)
    session_id = models.UUIDField(default=uuid.uuid4, unique=True)  # 会话唯一标识
    user_id = models.IntegerField()  # 用户ID
    start_time = models.DateTimeField(default=timezone.now)  # 使用 timezone.now 作为默认值
    end_time = models.DateTimeField(null=True)  # 会话结束时间

    class Meta:
        ordering = ['-start_time']

class RealtimeDetectionResult(models.Model):
    """检测结果模型，记录每个检测到的物体"""
    id = models.AutoField(primary_key=True)
    session = models.ForeignKey(
        RealtimeMonitoring,
        on_delete=models.SET_NULL,  # 如果会话被删除，保留检测结果
        related_name='detections',
        null=True,  # 允许为空
        blank=True  # 允许在表单中为空
    )
    class_id = models.IntegerField()  # YOLOv8 类别ID
    class_name = models.CharField(max_length=100)  # 类别名称
    start_time = models.DateTimeField(db_index=True)  # 物体出现的起始时间
    end_time = models.DateTimeField(db_index=True)  # 物体消失的结束时间
    confidence = models.FloatField()  # 置信度
    created_at = models.DateTimeField(auto_now_add=True)

    def save(self, *args, **kwargs):
        if isinstance(self.start_time, (int, float)):
            # 直接使用本地时间
            self.start_time = datetime.fromtimestamp(self.start_time)
        if isinstance(self.end_time, (int, float)):
            # 直接使用本地时间
            self.end_time = datetime.fromtimestamp(self.end_time)
        super().save(*args, **kwargs)
    class Meta:
        ordering = ['start_time']

